package com.syc.test.translate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Optional;
import com.optimaize.langdetect.LanguageDetector;
import com.optimaize.langdetect.LanguageDetectorBuilder;
import com.optimaize.langdetect.i18n.LdLocale;
import com.optimaize.langdetect.ngram.NgramExtractors;
import com.optimaize.langdetect.profiles.LanguageProfile;
import com.optimaize.langdetect.profiles.LanguageProfileReader;
import com.optimaize.langdetect.text.CommonTextObjectFactories;
import com.optimaize.langdetect.text.TextObject;
import com.optimaize.langdetect.text.TextObjectFactory;
import com.syc.test.TranslateLanguageEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 翻译工具类
 *
 * @Author shifuming
 * @Date 2022-05-24
 */
@Slf4j
public class TranslateUtil {

    private static List<LanguageProfile> languageProfiles;

    private static LanguageDetector languageDetector;

    private static TextObjectFactory textObjectFactory;

    private static List<Map<String, String>> transApiList = new ArrayList<>();

    private static final String TRANS_API_HOST = "http://api.fanyi.baidu.com/api/trans/vip/translate";

    private static final String APP_ID = "appid";

    private static final String SECURITY_KEY = "securityKey";

    private static final ScriptEngineManager scriptEngineManager = new ScriptEngineManager();

    private static final ScriptEngine engine = scriptEngineManager.getEngineByExtension("js");

    private static final Random random = new Random();

    private TranslateUtil() {
    }

    static {
        Map<String, String> trans1 = new HashMap<>(2);
        trans1.put(APP_ID, "20210702000877929");
        trans1.put(SECURITY_KEY, "nUtOnkt18ypsCpBOLbuJ");
        Map<String, String> trans2 = new HashMap<>(2);
        trans2.put(APP_ID, "20210702000878104");
        trans2.put(SECURITY_KEY, "IS6XX1U5iMMx6idoTrC1");
        transApiList.add(trans1);
        transApiList.add(trans2);
        try {
            //加载所有内置语种
            languageProfiles = new LanguageProfileReader().readAllBuiltIn();
            // 创建识别器
            languageDetector = LanguageDetectorBuilder.create(NgramExtractors.standard()).withProfiles(languageProfiles).minimalConfidence(0.7).build();
            // 创建文本对象工厂
            textObjectFactory = CommonTextObjectFactories.forDetectingOnLargeText();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String detectLanguage(String text) {
        if (StringUtils.isBlank(text)) {
            return null;
        }
        // 识别
        TextObject textObject = textObjectFactory.forText(text);
        Optional<LdLocale> lang = languageDetector.detect(textObject);
        return lang.isPresent() ? lang.get().toString() : null;
    }

    public static boolean isSimpleChinese(String text) {
        if (StringUtils.isEmpty(text)) {
            return false;
        }
        String filterString = HtmlUtils.splitAndFilterString(text, text.length());
        return TranslateLanguageEnum.Simplified_Chinese.getAbbreviation().equalsIgnoreCase(detectLanguage(filterString));
    }

    public static String execute(String text){
        if(true){
            return text;
        }
        Map<String, String> map = new HashMap<>();
        map.put("content",text);
        try {
            Map<String, String> resultMap = toTranslateSimpleChinese(map, "https://openapi.youdao.com/api", "03a8e0fef5b8bab6", "ctwcKGZH4l77D2SEiDtEeknsW6LNL2H8");
            String translateContent = resultMap.get("content");
            return translateContent;
        }catch (Exception e){
            System.out.println("翻译失败");
        }
        return text;
    }


    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        String content="<html> <head></head> <body>  <p style=\"margin-top: 20px !important;\">China’s modernization and its relationship with the West </p>  <p style=\"margin-top: 20px !important;\">In conversation with Mr Liu Jianchao, Minister of the International Department of the Central Committee of the Communist Party of China.</p>  <p style=\"margin-top: 20px !important;\">Last October the 20th National Congress of the Communist Party of China laid out a blueprint for China’s future development. The term ‘Chinese modernization’ was introduced and left the world perplexed.</p>  <p style=\"margin-top: 20px !important;\">This also comes at a time when the relationship between China and the UK is in a difficult spot. Following David Cameron’s attempts to usher in a ‘golden era of cooperation,’ relations with Beijing have become more complex to manage.</p>  <p style=\"margin-top: 20px !important;\">Bilateral ties are strained as the UK, and other countries look inward at securing supply chains and strategic industries while Beijing seeks ‘self-reliance’. However, both economies remain deeply entwined. This, along with global common causes such as the climate crisis, offer opportunities for partnership and dialogue between London and Beijing to re-emerge. </p>  <p style=\"margin-top: 20px !important;\"> This conversation considers: </p>  <p style=\"margin-top: 20px !important;\"> What is Chinese modernization and what does it mean for the world? </p>  <p style=\"margin-top: 20px !important;\"> Where can the UK and Chinese governments find common ground? </p>  <p style=\"margin-top: 20px !important;\"> How powerful are the BRICS countries? What does it mean for China’s development? </p>  <p style=\"margin-top: 20px !important;\">As with all members events, questions from the audience drive the conversation.</p>  <p style=\"margin-top: 20px !important;\">Major policy speeches, Q&amp;As with heads of state and panel discussions with influential authors, academics and policymakers, plus topic primers, screening rooms, webinars and receptions. Open to all members (including corporate members), usually on the record.</p> </body></html>";
        System.out.println("翻译前："+content);
        map.put("content", content);
        Map<String, String> resultMap = toTranslateSimpleChinese(map, "https://openapi.youdao.com/api", "03a8e0fef5b8bab6", "ctwcKGZH4l77D2SEiDtEeknsW6LNL2H8");
        String translateContent = resultMap.get("content");
        translateContent=removeBlankSpace(translateContent);
        System.out.println("翻译后："+translateContent);
    }

    public static String removeBlankSpace(String content){
        Pattern pattern = Pattern.compile("<.*?>");
        Matcher matcher = pattern.matcher(content);
        while(matcher.find()){
            String group = matcher.group();
            content=content.replace(group,group.replaceAll("\\s",""));
        }
        return content;
    }

    public static Map<String, String> toTranslateSimpleChinese(Map<String, String> fieldMap, String url, String appKey, String appSecurity) {
        return toYouDaoTranslate(fieldMap, "auto", "zh-CHS", url, appKey, appSecurity);
    }

    public static Map<String, String> toYouDaoTranslate(Map<String, String> fieldMap, String from, String to, String url, String appKey, String appSecurity) {
        if (fieldMap != null) {
            Map<String, String> resultMap = new HashMap<>(fieldMap.size());
            // 处理转义字符
            handleScript(fieldMap);
            Pattern compile = Pattern.compile("<.*?>");
            // 随机选取一个
            for (Map.Entry<String, String> entry : fieldMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getValue())) {
                    Map<String,String> tagMap=new HashMap<>();
                    // 处理图片标签
                    List<String> imgList = new ArrayList<>();
                    String value = handleImgTag(entry.getValue(), imgList);
                    StringBuilder translateValue = new StringBuilder();
                    String resultString = null;
                    int size = value.length() / 5000 + 1;
                    for (int i = 0; i < size; i++) {
                        String readyValue = "";
                        // 构建请求参数
                        if (i == size - 1) {
                            readyValue = value.substring(5000 * i);
                        } else {
                            readyValue = value.substring(5000 * i, 5000 * (i + 1));
                        }
                        Matcher matcher = compile.matcher(readyValue);
                        int index=0;
                        while (matcher.find()){
                            String group = matcher.group();
                            if(!tagMap.containsKey(group)){
                                index++;
                                String shortTag=index+"";
                                readyValue=readyValue.replace(group, String.format("<%s>", shortTag));
                                tagMap.put(group,shortTag);
                            }
                        }
                        Map<String, String> params = YouDaoTranslateHttp.buildParams(readyValue, from, to, appKey, appSecurity);
                        try {
                            resultString = YouDaoTranslateHttp.requestForHttp(params, url);
                            resultString = removeBlankSpace(resultString);
                            for (String key : tagMap.keySet()) {
                                String val = tagMap.get(key);
                                resultString=resultString.replace(String.format("<%s>", val),key);
                            }
                        } catch (IOException e) {
                            log.error("====YouDaoTranslateHttp error====", e);
                        }
                        if (StringUtils.isNotBlank(resultString)) {
                            int count = 0;
                            if (resultString.contains("\n")) {
                                resultString = resultString + "\n";
                            }
                            while(resultString.contains("\n")) {
                                if (count % 2 == 0) {
                                    resultString = resultString.replaceFirst("\n", "<p style=\"margin-top: 20px !important;\">");
                                } else {
                                    resultString = resultString.replaceFirst("\n", "</p>");
                                }
                                count++;
                            }

                            // 替换原来的图片链接
                            for (int j = 0; j < imgList.size(); j++) {
                                resultString = resultString.replaceFirst("\uD83D\uDE02", imgList.get(j));
                            }
                            translateValue.append(resultString);
                        }
                    }
                    resultMap.put(entry.getKey(), translateValue.toString());
                }
            }
            return resultMap;
        }
        return Collections.emptyMap();
    }

    public static Map<String, String> toBaiduTranslate(Map<String, String> fieldMap, String from, String to) {
        if (fieldMap != null) {
            Map<String, String> resultMap = new HashMap<>(fieldMap.size());

            // 处理转义字符
            handleScript(fieldMap);

            // 处理图片标签
            List<String> imgList = new ArrayList<>();
//            handleImgTag(fieldMap, imgList);

            // 随机选取一个
            Map<String, String> apiMap = transApiList.get(random.nextInt(2));
            for (Map.Entry<String, String> entry : fieldMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getValue())) {
                    String value = entry.getValue();
                    int size = value.length() / 5000 + 1;
                    StringBuilder translateValue = new StringBuilder();
                    for (int i = 0; i < size; i++) {
                        String readyValue = "";
                        // 构建请求参数
                        if (i == size - 1) {
                            readyValue = value.substring(5000 * i);
                        } else {
                            readyValue = value.substring(5000 * i, 5000 * (i + 1));
                        }
                        Map<String, String> params = BaiduTranslateHttp.buildParams(readyValue, from, to, apiMap.get(APP_ID), apiMap.get(SECURITY_KEY));
                        String resultString = BaiduTranslateHttp.post(TRANS_API_HOST, params);
                        if (StringUtils.isNotBlank(resultString)) {
                            JSONObject result = JSON.parseObject(resultString);
                            JSONArray jsonArray = result.getJSONArray("trans_result");
                            StringBuilder dstBuilder = new StringBuilder();
                            for (Object o : jsonArray) {
                                JSONObject jsonObject = (JSONObject) o;
                                dstBuilder.append(jsonObject.getString("dst"));
                            }
                            String dst = dstBuilder.toString();

                            while (StringUtils.isNotBlank(dst) && dst.endsWith("。")) {
                                dst = dst.substring(0, dst.length() - 1);
                            }
                            if (StringUtils.isNotBlank(dst)) {
                                dst = dst.replace("”", "\"");
                                dst = dst.replace("“", "\"");
                            }

                            // 替换原来的图片链接
                            for (int j = 0; j < imgList.size(); j++) {
                                dst = dst.replace("#{" + j + "}", imgList.get(j));
                            }
                            translateValue.append(dst);
                        }
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            log.error("====翻译失败===={}", JSON.toJSONString(fieldMap), e);
                        }
                    }
                    resultMap.put(entry.getKey(), translateValue.toString());
                }
            }
            return resultMap;
        }
        return Collections.emptyMap();
    }

    private static void handleScript(Map<String, String> fieldMap) {
        fieldMap.forEach((k, v) -> fieldMap.put(k, handleScript(v)));
    }

    private static String handleScript(String text) {
        if (StringUtils.isNotBlank(text)) {
            try {
                return (String) engine.eval("unescape('" + text + "')");
            } catch (ScriptException e) {
                log.error("====handleScript===={}", text, e);
            }
        }
        return text;
    }

    private static String handleImgTag(String text, List<String> imgList) {
        if (StringUtils.isNotBlank(text)) {
            text = text.replace("<p style=\"margin-top: 20px !important;\">", "\n");
            text = text.replace("</p>", "\n");
            while (text.contains("<img")) {
                int index1 = text.indexOf("<img");
                int index2 = text.indexOf(">", index1);
                String substring = text.substring(index1, index2 + 1);
                imgList.add(substring);
                text = text.substring(0, index1) + "\\uD83D\\uDE02" + text.substring(index2 + 1);
            }
        }
        return text;
    }

}
